package com.cls.business.controller;

import com.cls.business.entity.*;
import com.cls.business.service.*;
import com.cls.business.vo.DeclareTopicVO;
import com.cls.common.annotation.ControllerEndpoint;
import com.cls.common.controller.BaseController;
import com.cls.common.entity.MyConstant;
import com.cls.common.entity.QueryRequest;
import com.cls.common.entity.ResponseVO;
import com.cls.common.enums.DictEnum;
import com.cls.common.enums.EmailTextEnum;
import com.cls.common.enums.MessageEnum;
import com.cls.common.exception.MyException;
import com.cls.common.utils.EmailSenderUtil;
import com.cls.common.utils.MyUtil;
import com.cls.common.utils.StringUtils;
import com.cls.system.entity.SysDict;
import com.cls.system.entity.SysFile;
import com.cls.system.entity.User;
import com.cls.system.service.ISysDictService;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import com.cls.system.service.ISysFileService;

/**
 * 拟立项控制器
 *
 * @author wmm
 */
@Slf4j
@Validated
@Controller
@RequiredArgsConstructor
public class ItemController extends BaseController {

    private final IDeclareTopicService declareTopicService;

    private final ISysDictService sysDictService;

    private final ISysFileService sysFileService;

    private final IExpertExcel8ReviewService expertExcel8ReviewService;

    private final IMessageService messageService;

    private final ILogDeclareTopicService logDeclareTopicService;

    private final EmailSenderUtil emailSenderUtil;

    /**
     * 委托列表页面
     **/
    @GetMapping(MyConstant.VIEW_PREFIX + "biz/item/entrust")
    public String itemAnnualIndex(Model model) {
        List<SysDict> subjectType = sysDictService.findByParentCode(DictEnum.SUBJECT_TYPE.getCode());
        model.addAttribute("subjectType", subjectType);
        List<SysDict> planNos = sysDictService.findByParentCode(DictEnum.PLAN_NO.getCode());
        model.addAttribute("planNos", planNos);
        return MyUtil.view("business/entrust/item/item");
    }

    /**
     * 列表页面
     **/
    @GetMapping(MyConstant.VIEW_PREFIX + "biz/item")
    public String itemIndex(Model model) {
        List<SysDict> subjectType = sysDictService.findByParentCode(DictEnum.SUBJECT_TYPE.getCode());
        model.addAttribute("subjectType", subjectType);
        return MyUtil.view("business/item/item");
    }

    /**
     * 生成编码页面
     **/
    @GetMapping(MyConstant.VIEW_PREFIX + "biz/item/createCode")
    public String createCodeHtml(Model model) {
        //查询专家评审完成的计划
        List<Topic> topicList = declareTopicService.selectByStatusGroupByYear(DictEnum.ITEM_CHECK_PASSED.getCode(), DictEnum.ANNUAL.getCode());
        model.addAttribute("topicList", topicList);
        return MyUtil.view("business/item/createCode");
    }

    /**
     * 上传结项证书页面
     **/
    @GetMapping(MyConstant.VIEW_PREFIX + "biz/item/uploadItemFile/{declareTopicId}/{planId}")
    public String uploadItemFileHtml(@PathVariable Long planId, @PathVariable Long declareTopicId, Model model) {
        //查询专家评审完成的计划
        DeclareTopic declareTopic = declareTopicService.getById(declareTopicId);
        model.addAttribute("declareTopic", declareTopic);
        Long itemFileId = declareTopic.getItemFileId();
        SysFile itemFile;
        if (itemFileId != null) {
            itemFile = Optional.ofNullable(sysFileService.getById(itemFileId)).orElse(new SysFile());
        } else {
            itemFile = new SysFile();
        }
        model.addAttribute("itemFile", itemFile);
        model.addAttribute("planId", planId);

        return MyUtil.view("business/item/uploadItemFile");
    }


    /**
     * 评审结果页面
     *
     * @param declareTopicId
     * @return
     */
    @GetMapping(MyConstant.VIEW_PREFIX + "biz/item/detail/{declareTopicId}")
    public String itemResult(@PathVariable Long declareTopicId, Model model) {
        model.addAttribute("declareTopicId", declareTopicId);
        DeclareTopic byId = declareTopicService.getById(declareTopicId);
        Double score = byId.getScore();
        model.addAttribute("score", score);
        return MyUtil.view("business/item/result");
    }


    @GetMapping("biz/item/list")
    @ResponseBody
    @RequiresPermissions("item:list")
    public ResponseVO itemList(QueryRequest request, DeclareTopic declareTopic) {
        //必须查询审核通过的信息方可能展示
        List<String> codes = new ArrayList<>();
        codes.add(DictEnum.ITEM_CHECK_PASSED.getCode());
        codes.add(DictEnum.ITEM_PASSED.getCode());
        codes.add(DictEnum.ITEM_FAILED.getCode());
        codes.add(DictEnum.ITEM_CANCEL.getCode());
        codes.add(DictEnum.CONCLUDE_PASSED.getCode());
        codes.add(DictEnum.CONCLUDE_FAILED.getCode());
        declareTopic.setStatusTypeCodes(codes);
        if (StringUtils.isNotBlank(declareTopic.getYear())
                && StringUtils.isNotBlank(declareTopic.getPlanNo())) {
            declareTopic.setPeriod(declareTopic.getYear() + "-" + declareTopic.getPlanNo());
        } else if (StringUtils.isNotBlank(declareTopic.getYear())) {
            declareTopic.setPeriod(declareTopic.getYear());
        }

        PageInfo<DeclareTopicVO> declareTopics = this.declareTopicService.findDeclareTopicsForEvaluation(request, declareTopic);
        return ResponseVO.success(declareTopics);
    }


    /**
     * 生成编码
     * 根据年份查询此年份所有的拟立项审查通过的数据，进行生成编码并修改其状态为立项通过
     **/
    @ControllerEndpoint(operation = "生成编码", exceptionMessage = "生成编码失败")
    @PostMapping("biz/item/createCode/{year}")
    @ResponseBody
    public ResponseVO createCode(@PathVariable Integer year) {
        declareTopicService.createAnnualCode(year);
        return ResponseVO.success();
    }

    /**
     * 取消立项
     **/
    @ControllerEndpoint(operation = "取消立项", exceptionMessage = "取消立项失败")
    @PostMapping("biz/item/cancelItem/{declareTopicId}")
    @ResponseBody
    public ResponseVO cancelItem(@PathVariable Long declareTopicId, String checkResult) {
        DeclareTopic declareTopic = new DeclareTopic();
        declareTopic.setDeclareId(declareTopicId);
        declareTopic.setCheckResult(checkResult);
        declareTopic.setIsFinish(true);
        declareTopic.setStatusTypeCode(DictEnum.ITEM_CANCEL.getCode());
        declareTopicService.updateById(declareTopic);
        LogDeclareTopic logDeclareTopic = new LogDeclareTopic();
        logDeclareTopic.setDeclareId(declareTopicId);
        logDeclareTopic.setOperatorBy(getCurrentUser().getUserId());
        logDeclareTopic.setOperatorTime(new Date());
        logDeclareTopic.setReason(checkResult);
        logDeclareTopic.setStatusTypeCode(DictEnum.ITEM_FAILED.getCode());
        logDeclareTopic.setOperatorTypeCode(DictEnum.OPERATOR_CANCEL_ITEM.getCode());
        logDeclareTopicService.createLogDeclareTopic(logDeclareTopic);
        return ResponseVO.success();
    }


    /**
     * 上传立项证书
     **/
    @ControllerEndpoint(operation = "上传立项证书", exceptionMessage = "上传立项证书")
    @PostMapping("biz/item/uploadItemFile/{declareTopicId}/{planId}/{fileId}")
    @ResponseBody
    public ResponseVO uploadItemFile(@PathVariable Long planId, @PathVariable Long declareTopicId, @PathVariable Long fileId) {
        DeclareTopic declareTopic = declareTopicService.getById(declareTopicId);
        Long oldItemFileId = declareTopic.getItemFileId();
        declareTopic.setItemFileId(fileId);
        declareTopicService.updateById(declareTopic);
        //更新文件状态为已完成
        sysFileService.updateIsFinish(fileId, oldItemFileId);
        return ResponseVO.success();
    }

    /**
     * 发布立项证书
     **/
    @ControllerEndpoint(operation = "发布立项证书", exceptionMessage = "发布立项证书失败")
    @PostMapping("biz/item/publish/{declareTopicId}")
    @ResponseBody
    public ResponseVO publishItem(@PathVariable Long declareTopicId) {
        DeclareTopic declareTopic = declareTopicService.getById(declareTopicId);
        declareTopic.setIsItemPublish(true);
        declareTopicService.updateById(declareTopic);
        //查询用户
        ApplicantInfo applicantInfo = declareTopicService.findApplicantInfoById(declareTopicId);

        //发布消息  您申报的课题已经立项成功，请登录系统查看立项通知书。
        User currentUser = getCurrentUser();
        String message = String.format(EmailTextEnum.ITEM_PASSED_TEXT.getText(), declareTopic.getName());
        messageService.sendMessageById(message, currentUser, applicantInfo.getUserId());
        emailSenderUtil.sendEmail(EmailTextEnum.ITEM_PASSED.getText(),message,applicantInfo.getEmail());
        return ResponseVO.success();
    }

    /**
     * 发布结项证书
     **/
    @ControllerEndpoint(operation = "发布结项证书", exceptionMessage = "发布结项证书")
    @PostMapping("biz/item/entrust/publish/{declareTopicId}")
    @ResponseBody
    public ResponseVO publishResult(@PathVariable Long declareTopicId) {
        DeclareTopic declareTopic = new DeclareTopic();
        declareTopic.setDeclareId(declareTopicId);
        declareTopic.setIsItemPublish(true);
        declareTopicService.updateById(declareTopic);
        //查询用户
        ApplicantInfo applicantInfo = declareTopicService.findApplicantInfoById(declareTopicId);
        //发布消息  您申报的课题已经结项成功，请登录系统查看结项通知书。
        User currentUser = getCurrentUser();
        String message = String.format(EmailTextEnum.CONCLUDE_PASSED_TEXT.getText(), declareTopic.getName());
        messageService.sendMessageById(message, currentUser, applicantInfo.getUserId());
        emailSenderUtil.sendEmail(EmailTextEnum.CONCLUDE_PASSED.getText(),message,applicantInfo.getEmail());
        return ResponseVO.success();
    }

    /**
     * 魏起成
     * 导出结项鉴定统计表
     *
     * @param
     * @param response
     */
    @ControllerEndpoint(operation = "导出结项鉴定统计表", exceptionMessage = "导出Excel失败")
    @GetMapping("biz/item/export/{period}")
    @RequiresPermissions("evaluation:list")
    public void export(@PathVariable String period, HttpServletResponse response) {

        try {
            expertExcel8ReviewService.exportItemResult(period, response, DictEnum.ENTRUST.getCode());
        } catch (IOException e) {
            e.printStackTrace();
            throw new MyException("对不起，导出失败！");
        }
    }

}
